package com.red.wood.module.api.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.red.wood.common.util.CommonDao;
import com.red.wood.common.util.CommonUtils;
import com.red.wood.common.util.Page;
import com.red.wood.common.util.TokenUtils;
import com.red.wood.module.api.dao.ApiDao;

@Repository
public class ApiDaoImpl implements ApiDao{

	private static final Log log = LogFactory.getLog(ApiDaoImpl.class);
	
	@Autowired
    @Qualifier("primaryJdbcTemplate")
    private JdbcTemplate jdbcTemplate;
	
	@Autowired
	private CommonDao commonDao; 
	
	@Value("${service.public.url}")
	private String serviceUrl; 
	
	@Override
	public Map<String, Object> getPageData(Map<String, Object> param) {
		String count = "0";
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		
		count = listCount(param);
		list = listPageData(param);
		
		Map<String, Object> rs = new HashMap<String, Object>();
		rs.put("totalCount", count);
		rs.put("pageData", list);
		return rs;
	}
	
	@Override
	public List<Map<String, Object>> getApiCategoryInfo(String categoryNameStr) {
		StringBuffer sql = new StringBuffer();
		sql.append("select category_name from dashboard_api");
		StringBuffer conf = new StringBuffer();
		if(StringUtils.isNotBlank(categoryNameStr)) {
			conf.append(" where category_name in (");
			conf.append(categoryNameStr);
			conf.append(")");
		}else {
			conf.append(" where 1 = 2");
		}
		sql.append(conf);
		sql.append(" group by category_name");
		log.info("API分类SQL："+sql);
		
		return jdbcTemplate.queryForList(sql.toString());
	}
	
	@Override
	public List<Map<String, Object>> getApiReturnParametersInfo(String serviceId) {
		String sql = "select param_code as columns,param_type as type,param_remark as describes from dashboard_api_param where api_id = "+serviceId+" and type = 'OUT'";
		return jdbcTemplate.queryForList(sql);
	}
	
	@Override
	public List<Map<String, Object>> getApiRequestParametersInfo(String serviceId) {
		String sql = "select param_code as columns,param_type as type,'否' as isRequired,param_remark as describes from dashboard_api_param where api_id = "+serviceId+" and type = 'IN'";
		return jdbcTemplate.queryForList(sql);
	}
	
	@Override
	public List<Map<String, Object>> getApiServiceInfoByToken(String token) {
		String sql = "select group_concat(distinct(api_query_id)) as service_id,category_name from dashboard_token where token='"+token+"' group by category_name";
		return jdbcTemplate.queryForList(sql);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public String apiServicePublic(HttpServletRequest request) {
		String user = CommonUtils.valueOf(request.getSession().getAttribute("user"));
		Map<String,List<String>> map = (Map<String, List<String>>) request.getSession().getAttribute("apiInfo");
		String ip = CommonUtils.getLocalHostLANAddress().getHostAddress();
		String contextPath = request.getContextPath();
		int port = request.getServerPort();
		
		Map<String, Object> claims = new HashMap<String,Object>();
		claims.put("user",user);
		String token = TokenUtils.createJavaWebToken(claims);
		List<Map<String,Object>> datas = new ArrayList<Map<String,Object>>();
		for(Map.Entry<String,List<String>> entry : map.entrySet()) {
			String category_name = entry.getKey();
			List<String> valueList = entry.getValue();
			for(String api_query_id : valueList) {
				Map<String,Object> data = new HashMap<String,Object>();
				data.put("token", token);
				data.put("api_query_id", api_query_id);
				data.put("category_name", category_name);
				datas.add(data);
			}
		}
		
		commonDao.deleteTableData("delete from dashboard_token where token='"+token+"'");
		
		String sql = "insert into dashboard_token(token,api_query_id,category_name) values (?,?,?)";
		String columns = "token,api_query_id,category_name";
		commonDao.insertBatchTableData(datas, sql, columns,500);
		
		StringBuffer url = new StringBuffer();
		//url.append("http://").append(ip).append(":").append(port).append(contextPath).append("/index_api?token=").append(token);
		//牵涉到外网与内网，URL直接配置
		url.append(serviceUrl).append("?token=").append(token);
		return url.toString();
	}
	
	public String listCount(Map<String, Object> param) {
		StringBuffer sql = new StringBuffer();
		sql.append("select count(1) count from dashboard_api");
		sql.append(queryConf(param));
		Map<String, Object> map = jdbcTemplate.queryForList(sql.toString()).get(0);
		String count = map.get("count").toString();
		return count;
	}
	
	public List<Map<String, Object>> listPageData(Map<String, Object> param){
		Page page = (Page) param.get("page");
		int offset = (page.getPageNo() - 1) * page.getPageSize();
		StringBuffer sql = new StringBuffer();
		
		sql.append("select query_id as service_id,category_name,api_name as service_name from dashboard_api");
		sql.append(queryConf(param));
		
		sql.append(" limit " + page.getPageSize() + " offset " + offset+ " ;");
		log.info("API服务SQL："+sql);
		return jdbcTemplate.queryForList(sql.toString());
	}

	public StringBuffer queryConf(Map<String, Object> param) {
		StringBuffer sql = new StringBuffer();
		String category_name = CommonUtils.valueOf(param.get("category_name"));
		String serviceIdStr = CommonUtils.valueOf(param.get("serviceIdStr"));
		
		sql.append(" where 1 = 1");
		if(StringUtils.isNotBlank(category_name)) {
			sql.append(" and category_name='"+category_name+"'");
		}
		if(StringUtils.isNotBlank(serviceIdStr)) {
			sql.append(" and query_id in (");
			sql.append(serviceIdStr);
			sql.append(")");
		}else {
		    sql.append(" and 1 = 2");
		}
		return sql;
	}
}